"""
Case Type   : pagehack工具测试
Case Name   : pcr索引类型_pagehack解析结果校验_元组存储详情_tuple状态_td_id是否与TD槽对应
Create At   : 2025-10-25
Owner       : chen
Description :
    1.建表，创建索引，插入数据
    2.查询索引文件路径
    3.删除数据，继续插入数据
    4.解析
    5.查看解析结果，元组中td_id是否与TD槽对应
Expect      :
    1.成功
    2.成功
    3.成功
    4.成功
    5.成功
History     :
"""

import os
import re
import time
import unittest
from testcase.utils.Logger import Logger
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from yat.test import Node
from yat.test import macro

log = Logger()
primary_sh = CommonSH('PrimaryDbUser')

class Tools_Pagehack_Case0044(unittest.TestCase):
    def setUp(self):
        log.info(f'--------{os.path.basename(__file__)} start--------')
        self.constant = Constant()
        self.pri_node = Node('PrimaryDbUser')
        self.table_name = 't_pagehack_0044'
        self.index_name = 'i_pagehack_0044'

    def test_pagehack(self):
        text = '-------------step1: 建表，创建索引，插入数据; expect: 成功-------------'
        log.info(text)
        msg = primary_sh.check_connection_status(self.constant.START_STATUS_MSG)
        self.assertTrue(msg)
        create_table = f'''drop table if exists {self.table_name};
            create table {self.table_name}(c1 int)with (storage_type=ustore);
            create index {self.index_name} on 
                {self.table_name}(c1) with (index_type=pcr);
            insert into {self.table_name}(c1) 
                select 1 from generate_series(1,328);
            insert into {self.table_name}(c1) 
                select 2 from generate_series(1,328);
            insert into {self.table_name}(c1) 
                select 3 from generate_series(1,328);
            insert into {self.table_name}(c1) 
                select 4 from generate_series(1,328);
            insert into {self.table_name}(c1) 
                select 5 from generate_series(1,328);
            insert into {self.table_name}(c1) 
                select 6 from generate_series(1,328);
            '''
        res = primary_sh.execut_db_sql(create_table)
        log.info(res)
        self.assertIn(self.constant.CREATE_TABLE_SUCCESS, res)
        self.assertIn(self.constant.CREATE_INDEX_SUCCESS, res)
        self.assertIn('INSERT 0 328', res)
        self.assertEqual(res.count('INSERT 0 328'), 6)

        text = '-------------step2: 查询索引文件路径; expect: 成功-------------'
        log.info(text)
        select_sql = f"SELECT pg_relation_filepath('{self.index_name}');"
        res = primary_sh.execut_db_sql(select_sql)
        log.info(res)
        self.assertIn('(1 row)', res)
        index_path = str(res).splitlines()[-2].strip()

        text = '-------------step3: 删除数据，继续插入数据; expect: 成功-------------'
        log.info(text)
        select_sql = f"""delete from {self.table_name} where c1=1;
            delete from {self.table_name} where c1=2;
            delete from {self.table_name} where c1=3;
            delete from {self.table_name} where c1=4;
            delete from {self.table_name} where c1=5;
            insert into {self.table_name}(c1) 
                select 7 from generate_series(1,382);
            insert into {self.table_name}(c1) 
                select 4 from generate_series(1,382);
            insert into {self.table_name}(c1) 
                select 5 from generate_series(1,382);
            insert into {self.table_name}(c1) 
                select 6 from generate_series(1,382);"""
        res = primary_sh.execut_db_sql(select_sql)
        log.info(res)
        self.assertIn('DELETE 328', res)
        self.assertIn('INSERT 0 382', res)

        text = '-------------step4: 解析; expect: 成功-------------'
        log.info(text)
        time.sleep(10)
        shell = f'source {macro.DB_ENV_PATH}; ' \
            f'cd {macro.DB_INSTANCE_PATH} && ' \
            f'pagehack -f {index_path} -t ubtree_pcr_index'
        log.info(shell)
        msg = self.pri_node.sh(shell).result()
        log.info(msg)
        self.assertNotIn('ERROR', msg)

        text = '-------------step5: 查看解析结果; expect: 成功-------------'
        log.info(text)
        self.assertIn('page information of block 1', msg)
        self.assertIn('UBtree PCR Page TD information, nTDSlots = 4', msg)
        info = msg.split('page information of block')
        pattern = r'TD Slot #(\d+)[^,]*,\s*tdStatus:\s*([A-Z_]+(?: [A-Z_]+)?)'
        for i in range(1, len(info)):
            matches_precise = re.findall(pattern, info[i])
            tid = ''
            for slot, status in matches_precise:
                log.info(f"Slot #{slot}: Status = {status.strip()}")
                if 'TD_ACTIVE' in status:
                    tid = slot
            if tid == '':
                continue
            self.assertIn(f'td_id:{tid}', info[i])
            self.assertEqual(info[i].count('td_id:0'), 1)

    def tearDown(self):
        text = '------------------清理环境; expect: 成功------------------'
        log.info(text)
        drop_sql = f'''drop index if exists {self.index_name};
            drop table if exists {self.table_name} ;'''
        res = primary_sh.execut_db_sql(drop_sql)
        log.info(res)
        self.assertIn(self.constant.DROP_INDEX_SUCCESS_MSG, res)
        self.assertIn(self.constant.DROP_TABLE_SUCCESS, res)